﻿using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.X86;

namespace SimdTest2.Methods
{
    [Algorithm(true, AlgorithmType.Two)]
    public unsafe class TwoMethod : AlgorithmBase
    {
        public TwoMethod(int row, int col) : base(row, col)
        {
        }
        protected int[] _data;
        protected override void CreateData()
        {
            _data = new int[_size];
            Random random = new Random();
            for (int i = 0; i < _size; i++)
            {
                _data[i] = random.Next(999);
            }
        }
        protected override void OrdinaryMethod()
        {
            int elementToCount = _data[0];
            int count = 0;
            for (int i = 0; i < _size; i++)
            {
                if (elementToCount == _data[i])
                    count++;
            }
        }

        protected override void SimdMethod()
        {
            int count = 0;
            int vectorSize = Vector128<int>.Count;
            long limit = _size - (_size % vectorSize);
            fixed (int* pArray = _data)
            {
                int elementToCount = *pArray;
                var target = Vector128.Create(elementToCount);
                Vector128<int> equalMask = Vector128<int>.Zero;
                for (int i = 0; i < limit; i += vectorSize)
                {
                    Vector128<int> vector = *(Vector128<int>*)(pArray + i);
                    equalMask =Sse2.Add(equalMask, Sse2.CompareEqual(vector, target));
                }
                int* equalMaskPtr = (int*)&equalMask;
                for (int j = 0; j < vectorSize; j++)
                {
                    count += -*(equalMaskPtr + j);
                }
                // 处理剩余的元素
                for (long i = limit; i < _data.Length; i++)
                {
                    if (*(pArray + i) == elementToCount)
                        count++;
                }
            }
        }
    }
}
